﻿using System;

using PPT = Microsoft.Office.Interop.PowerPoint;
using System.Collections.Generic;
using Microsoft.Office.Interop.PowerPoint;

using AppUtils;

namespace PresentationUtils
{
    public class Presentation
    {
        private PPT.Presentation objPres;

        public delegate void OnPresentationEnd();
        public event OnPresentationEnd PresentationEnd;

        public Presentation(String fileName)
        {
            try
            {
                PPT.Presentations objPresSet = PPTControl.Presentations;

                // Open the presentation
                objPres = objPresSet.Open(fileName,
                    Microsoft.Office.Core.MsoTriState.msoFalse,
                    Microsoft.Office.Core.MsoTriState.msoTrue,
                    Microsoft.Office.Core.MsoTriState.msoTrue);

                objPres.SlideShowSettings.Run();
            }
            catch (Exception e)
            {
                Logger.log(string.Format("Failed to open presentation: {0}", e.Message));
            }
        }

        public void ClosePresentation()
        {
            if (objPres == null)
                return;

            try
            {
                objPres.Saved = Microsoft.Office.Core.MsoTriState.msoTrue;
                objPres.Close();

                PPTControl.PowerPoint.WindowState = PPT.PpWindowState.ppWindowMinimized;
            }
            catch (Exception e)
            {
                Logger.log(string.Format("Cannot close presentation: {0}", e.Message));
            }
            finally
            {
                objPres = null;
                if (PresentationEnd != null)
                    PresentationEnd();
            }
        }

        public delegate void PresentationAction();

        private void DoPresentationAction(PresentationAction pa)
        {
            try
            {
                if (objPres.SlideShowWindow.View.State == PpSlideShowState.ppSlideShowDone)
                {
                    Logger.log(string.Format("DoPresentationAction 'presentation is gone': {0}", pa.ToString()));
                    ClosePresentation();
                    return;
                }

                pa.Invoke();
            }
            catch (Exception e)
            {
                Logger.log(string.Format("Cannot 'DoPresentationAction': {0}", e.Message));
                ClosePresentation();
            }
        }

        public void First()
        {
            DoPresentationAction(delegate { objPres.SlideShowWindow.View.First(); });
        }

        public void Last()
        {
            DoPresentationAction(delegate { objPres.SlideShowWindow.View.Last(); });
        }

        public void Next()
        {
            DoPresentationAction(delegate { objPres.SlideShowWindow.View.Next(); });
        }

        public void Previous()
        {

            DoPresentationAction(delegate { objPres.SlideShowWindow.View.Previous(); });
        }

        public IList<String> SlideNames
        {
            get
            {
                IList<String> names = new List<String>();
                DoPresentationAction(delegate
                {
                    foreach (Slide slide in objPres.Slides)
                    {
                        names.Add(slide.Name);
                    }
                });
                return names;
            }
        }

        public int NumberOfSlides
        {
            get
            {
                int nr = 0;
                DoPresentationAction(delegate
                {
                    nr = objPres.Slides.Count;
                });

                return nr;
            }
        }

        public int CurrentSlideNumber
        {
            get
            {
                int nr = 1;
                DoPresentationAction(delegate
                {
                    nr = objPres.SlideShowWindow.View.CurrentShowPosition;
                });

                return nr;
            }
        }

        public void GoTo(int slideNo)
        {
            DoPresentationAction(delegate
            {
                if (slideNo < 1)
                    return;

                if (slideNo > NumberOfSlides)
                    return;

                objPres.SlideShowWindow.View.GotoSlide(slideNo, Microsoft.Office.Core.MsoTriState.msoFalse);
            });
        }
    }
}
